﻿/*
NTerm: A .NET based terminal abstraction library
Copyright (C) 2011  Bryan Perris

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace NTerm
{
    /// <summary>
    /// Defines a character cell structure
    /// </summary>
    /// <example>
    /// <code>
    /// // A black X on white background, that uses a single cell space
    /// CharacterCell cell = new CharacterCell();
    /// cell.character = 'X';
    /// cell.backgroundColor = ConsoleColor.White;
    /// cell.foregroundColor = ConsoleColor.Black;
    /// cell.CellType = CellType.Single;
    /// </code>
    /// </example>
    public struct CharacterCell
    {
        /// <summary>
        /// The ASCII character value of the cell
        /// </summary>
        public char Character;

        /// <summary>
        /// The background color of the cell
        /// </summary>
        public ConsoleColor BackgroundColor;

        /// <summary>
        /// The foreground color of the cell
        /// </summary>
        public ConsoleColor BoregroundColor;

        /// <summary>
        /// The cell spacing type of the cell
        /// </summary>
        public CellType CellType;

        /// <summary>
        /// Returns a hash code for this CharacterCell
        /// </summary>
        /// <returns>A 32-bit signed integer hash code</returns>
        public override int GetHashCode()
        {
            return ((int)Character ^ (((int)BackgroundColor << 8) | ((int)BoregroundColor))) + (int)CellType;
        }

        /// <summary>
        /// Determines whether this instance and another specified object, which has to be a type of CharacterCell, are the same value
        /// </summary>
        /// <param name="obj">The CharacterCell to compare this instance</param>
        /// <returns>true if obj is a CharacterCell and its value is the same as this instance; otherwise, false</returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            if (!obj.GetType().Equals(typeof(CharacterCell)))
                return false;

            CharacterCell cell = (CharacterCell)obj;

            if (Character.Equals(cell.Character) &&
                BackgroundColor.Equals(cell.BackgroundColor) &&
                BoregroundColor.Equals(cell.BoregroundColor) &&
                CellType.Equals(cell.CellType))
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// Determines whether this instance and another specified CharacterCell are the same value
        /// </summary>
        /// <param name="cell">The CharacterCell to compare this instance</param>
        /// <returns>true if obj's value is the same as this instance; otherwise, false</returns>
        public bool Equals(CharacterCell cell)
        {
            return Equals(cell);
        }

        /// <summary>
        /// Performs the equals operation on two specified CharacterCell instances
        /// </summary>
        /// <param name="cellA">the first CharacterCell instance</param>
        /// <param name="cellB">the second CharacterCell instance</param>
        /// <returns>True if cellA is equal to cellB, otherwise, false</returns>
        public static bool operator ==(CharacterCell cellA, CharacterCell cellB)
        {
            return cellA.Equals(cellB);
        }

        /// <summary>
        /// Performs the not equal operation on two specified CharacterCell instances
        /// </summary>
        /// <param name="cellA">the first CharacterCell instance</param>
        /// <param name="cellB">the second CharacterCell instance</param>
        /// <returns>True if cellA is not equal to cellB, otherwise, false</returns>
        public static bool operator !=(CharacterCell cellA, CharacterCell cellB)
        {
            return !cellA.Equals(cellB);
        }

        /// <summary>
        /// Returns a System.String representation of this instance
        /// </summary>
        /// <returns>A System.String value of this instance</returns>
        public override string ToString()
        {
            return new string(new char[] { Character });
        }
    }
}
